#########################################################################
#                         nodeutils.py : Node Utilities					#
#																		#
#########################################################################

#!/usr/bin/env python

# Imports
import os, re, subprocess as sb

import vm
import pm
import xenstoreutils
import networkutils
import checkpointutils

# Enumerates and returns a list domain ID's of live nodes on host (parses xm list)
def EnumVMDomIDs():
	
	# Create list
	domIDList = []
	
	# Parse xm list
	xmListDump = os.popen("/usr/sbin/xm list")
	for line in xmListDump:
		b=re.sub("\s+",'|',line)
		x=b.split('|')
		if x[1]!="ID" and x[1]!="0":
			domIDList.append(int(x[1]))
	
	# Return
	return domIDList


# Gets the /local/domain/<domid> and /vm/<uuid> vars for a VM and returns as a dictionary
def GetDomainCfgVars(domID):
	
	# Create a dictionary to hold the <item, value> pairs we get
	vmVars = {}
	
	# Save a copy of the domain path
	domPath = '/local/domain/' + str(domID)
	
	# Enumerate the domain path and add to vmVars
	vmVars.update(xenstoreutils.EnumerateDir(domPath))
	
	# Enumerate the /vm/<uuid>/ path
	vmFolderPairs = xenstoreutils.EnumerateDir(vmVars['vm'])
	
	# Iterate over the /vm/<uuid>/ items
	for key, val in vmFolderPairs.items():
		
		# Save it if we don't already have it, and its not the 'image' folder
		if key not in vmVars and key != 'image':
			vmVars[key] = val
	
	# Return the dictionary
	return vmVars

# Get image config vars from /vm/<uuid>/image
def GetImageConfigVars(domID):

	# Get the VM path based on domid
	vmPath = xenstoreutils.ReadVal('/local/domain/' + str(domID) + '/vm')
	
	# Enumerate the /vm/<uuid>/image vars
	imageVars = xenstoreutils.EnumerateDir(vmPath + '/image')
	
	# Return
	return imageVars

# Get network (VIF) config vars
def GetNetworkConfigVars(domID):

	# Create a list to hold what we get
	vifDictList = []
	
	# Save a copy of the vif path
	vifPath = '/local/domain/' + str(domID) + '/device/vif'
	
	# Get a list of the VIF numbers
	vifList = xenstoreutils.ListDir(vifPath)

	# Create a list to hold the backend paths
	backendPaths = []
	
	# Iterate over disks and save the backend paths
	for vifItem in vifList:
	
		# Append to the path list
		backendPaths.append(xenstoreutils.ReadVal(vifPath + '/' + vifItem + '/backend'))
	
	# Iterate over the backend paths to get the stuff we need
	for backendPath in backendPaths:
		
		# Get a list of all the pairs for this disk
		vifVars = xenstoreutils.EnumerateDir(backendPath)
		
		# Save
		vifDictList.append(vifVars)
		
	# Return
	return vifDictList

# Get VBD config vars
def GetVBDCfgVars(domID):

	# Create a list to hold our dictionaries
	vbdDictList = []

	# Save the vbd path
	vbdPath = '/local/domain/' + str(domID) + '/device/vbd'

	# Get a list the disks for our domid
	diskList = xenstoreutils.ListDir(vbdPath)
	
	# Create a list to hold the backend paths
	backendPaths = []
	
	# Iterate over disks and save the backend paths
	for diskItem in diskList:
	
		# Append to the path list
		backendPaths.append(xenstoreutils.ReadVal(vbdPath + '/' + diskItem + '/backend'))
	
	# Iterate over the backend paths to get the stuff we need
	for backendPath in backendPaths:
		
		# Get a list of all the pairs for this disk
		diskVars = xenstoreutils.EnumerateDir(backendPath)
		
		# Save
		vbdDictList.append(diskVars)

	# Return
	return vbdDictList

# Builds a VM object (static fields) based on domain ID
def BuildVMObj(domID):

	# Create a new VM object
	myVM = vm.VM()
	
	# Set the domain id
	myVM.domID = domID
	
	# Set the state
	myVM.state = "RUNNING"
	
	# Get the domain config vars
	myVM.domainCfgVars = GetDomainCfgVars(myVM.domID)
	
	# Get the image config vars
	myVM.imageCfgVars = GetImageConfigVars(myVM.domID)
	
	# Get the network config vars
	myVM.networkCfgVars = GetNetworkConfigVars(myVM.domID)
	
	# Get the VDB config vars
	myVM.vbdCfgVars = GetVBDCfgVars(myVM.domID)
	
	# Set the ip
	myVM.IP = networkutils.GetIP(myVM.GetHostname())
	
	# Get the snapshots
	myVM.snapshotList = checkpointutils.ListSS(myVM.domainCfgVars['uuid'])
	
	# Return
	return myVM
	
